#include <sys/time.h>
#include "cmdgm.h"
#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "../cmd/cmdapi.h"
#include "../cmdfront/cmduserinfo.h"
#include "commmsg.h"
#include "CTSizeString.h"
#include "net/CTBinhex.h"
#include "MsgMoveTo.pb.h"
#include "MsgWorldBoss.pb.h"
#include "MsgPartner.pb.h"
#include "MsgTreasure.pb.h"
#include "MsgBattle.pb.h"
#include "MsgNotify.pb.h"
#include "MsgMatrix.pb.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_GM_PLAYER, CCmdGMPlayer);

int CCmdGMPlayer::Do(void* pData)
{
    CT_ASSERT(pData);

#ifdef _DEBUG
    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_GM_PLAYER ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_GM_PLAYER, pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    _chSubCmd = stReq.sub_type();
    stAns.set_sub_type(_chSubCmd);
    _uiGID = 0;

    if (ID_GM_PLAYER_SUB_INFO_TOKEN == _chSubCmd)
    {
        if (!stReq.has_name())
        {
            return AnsClients(ERROR_GM_INFO_NO_COMPLETE);
        }

        CTSizeString<USER_TOKEN_LEN> szUserToken;
        szUserToken.Set("%s", stReq.name().c_str());

        int iIndex = pstMainCtrl->m_stUserTokenToGID.HashFind(szUserToken);
        if (iIndex < 0)
        {
             return AnsClients(ERROR_GM_NO_RECORD_GID);
        }

        _uiGID = pstMainCtrl->m_stUserTokenToGID[iIndex]._uiNowUseGID;
    }
    else if (ID_GM_PLAYER_SUB_SEND_INNER_CMD == _chSubCmd)
    {
        if (stReq.has_gid())
        {
            _uiGID = (unsigned int)stReq.gid();
        }

        iRet = SendInnerReq();
        return AnsClients(iRet);
    }
    else if (ID_GM_PLAYER_SUB_GET_HELP == _chSubCmd)
    {
        return AnsClients(GetHelpInfo());
    }
    else
    {
        if (!stReq.has_gid())
        {
            return AnsClients(ERROR_GM_INFO_NO_COMPLETE);
        }

        _uiGID = (unsigned int)stReq.gid();
    }

#if 0
    //检查登录
    if (!pstMainCtrl->IsLogin(_uiGID, stEnpHead))
    {
        return AnsClients(RET_NOT_LOGIN);
    }
#endif

    return LogicDo(RET_OK);

#else
    return AnsClients(RET_OK);
#endif
}

int CCmdGMPlayer::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, _uiGID);
    ASSERT_PLAYER_PREPARED(_uiGID);

    PREPARE_PLAYER_DETAIL_INFO(this, _uiGID);
    ASSERT_PLAYER_DETAIL_PREPARED(_uiGID);

    PREPARE_UNACT_PARTNER_INFO(this, _uiGID);
    ASSERT_UNACT_PARTNER_PREPARED(_uiGID);

    PREPARE_PLAYER_SNS_DETAIL_INFO(this, _uiGID);
    ASSERT_PLAYER_SNS_DETAIL_PREPARED(_uiGID);

    PREPARE_PLAYER_DETAIL_EX1_INFO(this, _uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no base data user(%u)", _uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBase = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no detail data user(%u)", _uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfo& stPlayerDetail = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stUnactPartnerInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no unact partner data user(%u)", _uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CUnactPartnerInfo& stUnactPartnerInfo = pstMainCtrl->m_stUnactPartnerInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", _uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerOnlineData& stPlayerOnline = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerSnsDetailInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user sns detail info error, uid = %u", _uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CPlayerSnsDetailInfo& stPlayerSnsDetailInfo = pstMainCtrl->m_stPlayerSnsDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->FindPlayerCacheData(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no Cache data user %u",_uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
	CPlayerCacheData& stPlayerCache = pstMainCtrl->m_stPlayerCacheDataHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no ex1 data user %u",_uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfoEx1& stPlayerDetailInfoEx1 = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    //查询类操作接口结束可以直接返回
    //修改类操作需要update db data

    CDropItem stDropItem;
    stDropItem.SetOssModule(OSS_MODULE_GM);
    unsigned int uiNotifyType = 0;
    switch (_chSubCmd)
    {
    case ID_GM_PLAYER_SUB_INFO_TOKEN://由token查询角色信息
    case ID_GM_PLAYER_SUB_INFO_GID://由GID查询角色信息
        GetInfoByGID(stPlayerBase, stPlayerDetail, stPlayerOnline);
        return AnsClients(RET_OK);
    case ID_GM_PLAYER_SUB_ADD_MONEY://修改金币银币
        {
            int iToAddGold = 0;
            if (stReq.datas_size() >= 3)
            {
                iToAddGold = stReq.datas(0);
                stPlayerBase.AddSilver(stPlayerBase._i64Silver, stReq.datas(1));
                stPlayerBase.ChangeIntValue(stPlayerBase._iRomany, stReq.datas(2));
            }

            if (stReq.datas_size() == 2)
            {
                iToAddGold = stReq.datas(0);
                stPlayerBase.AddSilver(stPlayerBase._i64Silver, stReq.datas(1));
            }

            if (stReq.datas_size() == 1)
            {
                iToAddGold = stReq.datas(0);            
            }

            if (iToAddGold > 0)
            {   
                stPlayerBase.AddGold(stPlayerBase._iGold, iToAddGold);
                pstMainCtrl->m_stOssMgr.TriggerMoney(stPlayerBase._uiGID, OSS_MONEY_ADD_GOLD, OSS_MODULE_GM, iToAddGold);
            }

            iRet = GetInfoByGID(stPlayerBase, stPlayerDetail, stPlayerOnline);
            uiNotifyType |= NOTIFY_USER_MONEY;
        }        
        break;

    case ID_GM_PLAYER_SUB_ADD_REPU://修改声望
        if (stReq.datas_size() >= 1)
        {           
            stDropItem.DropItem(ITEM_TYPE_REPUTATION, stReq.datas(0));            
            pstMainCtrl->m_stItemMgr.DropItem(0, _uiGID, stDropItem);
        }
        break;
    case ID_GM_PLAYER_SUB_ACT_PARTNER://获取激活伙伴列表
    case ID_GM_PLAYER_SUB_LIST_PARTNER://获取历史伙伴列表
    case ID_GM_PLAYER_SUB_PARTNER_ATTR://查看伙伴属性
        pstMainCtrl->m_stPartnerMgr.GMDealPartner(stPlayerBase, stPlayerDetail,
            stPlayerOnline, stUnactPartnerInfo, stPlayerDetailInfoEx1, stReq,
            stAns);
        return AnsClients(RET_OK);
    case ID_GM_PLAYER_SUB_CHG_PARTNER_LEVEL://修改伙伴等级
    case ID_GM_PLAYER_SUB_CHG_PARTNER_EXP://修改伙伴经验
    case ID_GM_PLAYER_SUB_CHG_PARTNER_FAVOR://修改伙伴好感度
        iRet = pstMainCtrl->m_stPartnerMgr.GMDealPartner(stPlayerBase,
            stPlayerDetail, stPlayerOnline, stUnactPartnerInfo,
            stPlayerDetailInfoEx1, stReq, stAns);
        break;
    case ID_GM_PLAYER_SUB_ROLE_ATTR://查看角色属性
        pstMainCtrl->m_stRoleMgr.GMDealRole(stPlayerBase, stPlayerDetail, stPlayerOnline, stReq, stAns);
        return AnsClients(RET_OK);
    case ID_GM_PLAYER_SUB_ADD_LEVEL://修改角色等级
    case ID_GM_PLAYER_SUB_ADD_EXP://修改角色经验
        iRet = pstMainCtrl->m_stRoleMgr.GMDealRole(stPlayerBase, stPlayerDetail, stPlayerOnline, stReq, stAns);
        if(!iRet)
        {
            iRet = GetInfoByGID(stPlayerBase, stPlayerDetail, stPlayerOnline);
        }
        uiNotifyType |= NOTIFY_ROLE_INFO;
        break;
    case ID_GM_PLAYER_SUB_ADD_HUNLI://修改角色魂力 也可以修改QQ好友邀请摇奖券
        if (stReq.datas_size() >= 1)
        {
            stPlayerBase._iHunli += stReq.datas(0);
            if (stPlayerBase._iHunli < 0)
            {
                stPlayerBase._iHunli = 0;
            }
        }

        if (stReq.datas_size() >= 2)
        {
            stPlayerDetailInfoEx1._stQQFriend._iCertiCount += stReq.datas(1);
            if (stPlayerDetailInfoEx1._stQQFriend._iCertiCount < 0)
            {
                stPlayerDetailInfoEx1._stQQFriend._iCertiCount = 0;
            }
        }

        GetInfoByGID(stPlayerBase, stPlayerDetail, stPlayerOnline);
        break;
    case ID_GM_PLAYER_SUB_SET_FINISH_TASK:
        {
            int iTaskId = stReq.datas(0);
            iRet = pstMainCtrl->m_stTaskMgr.GMSetTaskFinished(iTaskId, stPlayerOnline._stUserTask);

            stPlayerOnline._stUserTask.GetData(stPlayerBase._stUserTaskData);
        }
        break;
    case ID_GM_MAINCTRL_OFFSET_TIME:
        {
            const char * pInputTime = stReq.name().c_str();
            if (strlen(pInputTime) >= 10)
            {                
                int iTargetTime = CTTimeUtils::GetTsFromString(pInputTime);
                if (iTargetTime <= pstMainCtrl->m_iNow || iTargetTime < 0)
                {
                    CT_ERROR(("%s, %s", pInputTime, ctime((const time_t *)&pstMainCtrl->m_iNow)));
                    return AnsClients(RET_SYS_ERROR);  
                }
                            
                CZoneData& stZoneData = pstMainCtrl->m_stZoneOnlineData._stZoneData;
                stZoneData._iTimeOffSet += (iTargetTime - pstMainCtrl->m_iNow);
                CVarObjectKey stKey;
                stKey.m_chDataType = DT_ZONE_DATA;
                stKey.m_u64ID = stZoneData._uiZoneID;
                pstMainCtrl->UpdateData(stKey, stZoneData, VOP_UPDATE);
                iRet = RET_OK;
            }
            else
            {
                CT_ERROR(("%s", pInputTime));
                return AnsClients(RET_SYS_ERROR);  
            }
        }
        break;

    case ID_GM_INSTANCE_FULL:
        {
            unsigned char ucInstanceType = stReq.datas(0) & 0xFF;
            if (ucInstanceType < CInstanceConfigData::INSTANCE_TYPE_MIN
                || ucInstanceType > CInstanceConfigData::INSTANCE_TYPE_MAX)
            {
                iRet = RET_SYS_ERROR;
            }
            else
            {
                switch (ucInstanceType)
                {
                case 1:
                    stPlayerOnline._stUserInstance._stInstanceData._stHasOpenedInstanceData._usMainInstanceData = MAX_INSTANCE_MAIN_CONFIG_COUNT - 1;
                    break;
                case 2:
                    stPlayerOnline._stUserInstance._stInstanceData._stHasOpenedInstanceData._usChallengeInstanceData = MAX_INSTANCE_CHALLENGE_CONFIG_COUNT - 1;
                    break;
                default:
                    stPlayerOnline._stUserInstance._stInstanceData._stHasOpenedInstanceData._aucBranchInstances[ucInstanceType - CInstanceConfigData::INSTANCE_TYPE_CHALLENGE]
                                    = MAX_INSTANCE_BRANCH_CONFIG_COUNT;
                    break;
                }

                stPlayerOnline._stUserInstance.GetData(stPlayerBase._stInstanceData);
            }
        }
        break;
    case ID_GM_PLAYER_SUB_ADD_ITEM:  //在背包中增加物品
        {
            if (stReq.datas_size() >= 3)
            {
                CDropItemData stDropItemData;
                stDropItemData._ucItemType = stReq.datas(0);
                stDropItemData._usItemConfigID = stReq.datas(1);
                stDropItemData._iItemCount = stReq.datas(2);
                
                stDropItem.Drop(stDropItemData);
                pstMainCtrl->m_stItemMgr.DropItem(NULL, _uiGID, stDropItem);

            }
            uiNotifyType |= NOTIFY_BAG_INFO;
        }
        break;
    case ID_GM_ADD_GARDEN_DATA: //花园数据
        {
            if (stPlayerSnsDetailInfo._stMyInfo._stGardenData._shSeedCount == 0)
            {
                stPlayerSnsDetailInfo._stMyInfo._stGardenData._shSeedCount += 10;
            }

            if (stPlayerSnsDetailInfo._stMyInfo._stGardenData._chHoeCount == 0)
            {
                stPlayerSnsDetailInfo._stMyInfo._stGardenData._chHoeCount += 10;
            }
        }
        break;
    case ID_GM_PLAYER_SUB_SET_ACADMY:
        {
            if (stReq.datas_size() >= 1)
            {
                stPlayerBase._ucAcademy = stReq.datas(0);
                stPlayerSnsDetailInfo._stCommInfo._ucAcademy = stReq.datas(0);
                iRet = RET_OK;
                uiNotifyType |= NOTIFY_ROLE_INFO;
            }
        }
        break;
    case ID_GM_PLAYER_SUB_GET_MATRIX://获取主阵形列表
        iRet = pstMainCtrl->m_stMatrixMgr.GMDealMatrix(stPlayerDetail, stReq, stAns);
        return AnsClients(iRet);
    case ID_GM_PLAYER_SUB_ADD_FATE_FORCE:
        {
            if (stReq.datas_size() >= 1)
            {
                stPlayerBase._iFateForce += stReq.datas(0);
                iRet = RET_OK;
            }
        }
        break;
    case ID_GM_PLAYER_SUB_DEFEND_ONLINE:
        {
            stPlayerOnline._iDefTotalOnlineTime = stReq.datas(0);
            stPlayerBase._iDefTotalOnlineTime = stReq.datas(0);
            /*
            CPlayerSnsCommInfo & stSnsOnlineInfo = stPlayerSnsDetailInfo._stCommInfo;
            stSnsOnlineInfo._iTotalOnlineTime = stReq.datas(0);
            stSnsOnlineInfo._iLastRecordTime = pstMainCtrl->m_iNow;
            {
                int iTmpWarnTimes = 0;
                if( stSnsOnlineInfo._iTotalOnlineTime<3600 )
                {
                    iTmpWarnTimes = 0;
                }
                else if( stSnsOnlineInfo._iTotalOnlineTime>=3600 && stSnsOnlineInfo._iTotalOnlineTime<7200 )
                {
                    iTmpWarnTimes = 1;
                }
                else if( stSnsOnlineInfo._iTotalOnlineTime>=7200 && stSnsOnlineInfo._iTotalOnlineTime<10500 )
                {
                    iTmpWarnTimes = 2;
                }
                else if( stSnsOnlineInfo._iTotalOnlineTime>=10500 && stSnsOnlineInfo._iTotalOnlineTime<10800 )
                {
                    iTmpWarnTimes = 3;
                }
                else if( stSnsOnlineInfo._iTotalOnlineTime>=10800 )
                {
                    iTmpWarnTimes = 4;
                }
                stSnsOnlineInfo._iWarnTimes = iTmpWarnTimes;
            }
            */
        }
        break;
    case ID_GM_PLAYER_SUB_DEFEND_OFFLINE:
        {
            /*
            CPlayerSnsCommInfo & stSnsOnlineInfo = stPlayerSnsDetailInfo._stCommInfo;
            stSnsOnlineInfo._iTotalOnlineTime = stReq.datas(0);
            if( stSnsOnlineInfo._iTotalOfflineTime>=18000 )//5*60*60
            {
                stSnsOnlineInfo._iTotalOnlineTime = 0;
                stSnsOnlineInfo._iTotalOfflineTime = 0;
                stSnsOnlineInfo._iWarnTimes = 0;
            }
            */
        }
        break;
    case ID_GM_PLAYER_SUB_KILL_ENEMY:
        {
            if (stReq.datas_size() >= 2)
            {
                pstMainCtrl->m_stTaskMgr.TriggerKillEnemy(stPlayerOnline._stUserTask, stReq.datas(0), stReq.datas(1));
                iRet = RET_OK;
            }
        }
        break;
    case ID_GM_PLAYER_SUB_FINISH_INSTANCE:
        {
            if (stReq.datas_size() >= 1)
            {
                pstMainCtrl->m_stTaskMgr.TriggerFinishInstance(stPlayerOnline._stUserTask, stReq.datas(0), 1);
                iRet = RET_OK;
            }
        }
        break;
    case ID_GM_PLAYER_SUB_SET_VIP_LEVEL:
        {
            if (stReq.datas_size() >= 1)
            {
                int iPayGoldNums = stReq.datas(0);
                pstMainCtrl->m_stVipMgr.PrepaidGold(stPlayerBase, stPlayerDetail, iPayGoldNums, true);
                
                //stPlayerBase._chVipLevel = stReq.datas(0);
                pstMainCtrl->m_stNotifyMgr.Notify(stPlayerBase._uiGID, NOTIFY_SYSOPEN_INFO);
            }
        }
        break;
    case ID_GM_PLAYER_SUB_GET_TREASURE://查看角色秘宝
        pstMainCtrl->m_stTreasureMgr.GMDealTreasure(stPlayerDetail, stReq, stAns);
        return AnsClients(RET_OK);
    case ID_GM_PLAYER_SUB_SET_TREASURE://设置角色秘宝
    case ID_GM_PLAYER_SUB_SET_SPIRIT://设置角色灵力
        iRet = pstMainCtrl->m_stTreasureMgr.GMDealTreasure(stPlayerDetail,stReq, stAns);
        break;
    case ID_GM_PLAYER_SUB_FLUSH_ARENA_HERO_LIST:
        pstMainCtrl->m_stArenaMgr.FlushHeroList();
    case ID_GM_PLAYER_SUB_SET_ENERGY:
        if (stReq.datas(0) < 0 || stReq.datas(0) > MAX_ENERGY_GROW_COUNT)
        {
            stPlayerBase._stUserEnergy._shEnergy = MAX_ENERGY_GROW_COUNT;
        }
        else
        {
            stPlayerBase._stUserEnergy._shEnergy = stReq.datas(0);
            stPlayerBase._stUserEnergy._iEnergyGrowTime = pstMainCtrl->m_iNow;
        }
        pstMainCtrl->m_stNotifyMgr.Notify(_uiGID, NOTIFY_ROLE_INFO);
        break;
    case ID_GM_PLAYER_SUB_ADD_MUSEUM_SWEEP_COUNT:
        {
            stPlayerOnline._stUserInstance._stInstanceData._stMuseumInstanceData._iBuySweepCount = stReq.datas(0);
            stPlayerOnline._stUserInstance.GetData(stPlayerBase._stInstanceData);
        }
        break;
    case ID_GM_PLAYER_SUB_GET_STATUS://查看角色状态信息
        iRet = pstMainCtrl->m_stStatusMgr.GMDealStatus(stPlayerCache, stReq, stAns);
        return AnsClients(iRet);
    case ID_GM_PLAYER_SUB_ADD_STATUS://修改角色状态信息
        iRet = pstMainCtrl->m_stStatusMgr.GMDealStatus(stPlayerCache, stReq, stAns);
        return AnsClients(iRet);
    case ID_GM_PLAYER_SUB_GET_WORLD_BOSS_RANK:
    case ID_GM_PLAYER_SUB_SET_BOSS_WORLD_LEVEL:
    case ID_GM_PLAYER_SUB_SET_BOSS_MONSTER_HP:
        iRet = pstMainCtrl->m_stWorldBossMgr.GMDealWorldBoss(stPlayerDetail,
            stReq, stAns);
        return AnsClients(iRet);
    case ID_GM_PLAYER_SUB_GET_ACADEMY_BOSS_INFO:
        iRet = pstMainCtrl->m_stAcademyBossMgr.GMDealAcademyBoss(stReq, stAns);
        return AnsClients(iRet);
    case ID_GM_PLAYER_SUB_GET_ACT_STATUS:
    case ID_GM_PLAYER_SUB_SET_ACT_STATUS://设置活动运行时状态(1表示强制开启 0表示强制关闭)不用保存DB
        iRet = pstMainCtrl->m_stActMgr.GMDealAct(stReq, stAns);
        return AnsClients(iRet);
    case ID_GM_PLAYER_SUB_RESET_ELITE_COUNT:
        {
            stPlayerOnline._stUserInstance._stInstanceData._stEliteAtkStat.ClearResetCount();
            stPlayerOnline._stUserInstance.GetData(stPlayerBase._stInstanceData);
        }
        break;
    case ID_GM_PLAYER_SUB_RESET_SECRET_COUNT:
        {
            stPlayerOnline._stUserInstance._stInstanceData._stSecretInstanceData._iLastResetTime = 0;
            stPlayerOnline._stUserInstance.GetData(stPlayerBase._stInstanceData);
        }
        break;
    case ID_GM_PLAYER_SUB_SET_DAILY_TASK:
        {
            int iNewLiveness = stReq.datas(0);
            iRet = pstMainCtrl->m_stDailyTaskMgr.GMSetDailyTask(stPlayerOnline._stUserDailyTask, iNewLiveness);
        }
        break;
    case ID_GM_PLAYER_SUB_SET_DAILY_TASK_FINISH:
        {
            int iTaskId = stReq.datas(0);
            iRet = pstMainCtrl->m_stDailyTaskMgr.TriggerTaskFinish(stPlayerOnline._stUserDailyTask, iTaskId);
        }
        break;
    case ID_GM_PLAYER_SUB_OPEN_ENEMY_ATK_CITY:
        {
            if (pstMainCtrl->m_stEnemyAtkCityMgr.IsBegin())
            {
                pstMainCtrl->m_stEnemyAtkCityMgr.SetClose();
            }
            else
            {
                pstMainCtrl->m_stEnemyAtkCityMgr.SetBegin(pstMainCtrl->m_iNow);
            }
        }
        break;
    case ID_GM_PLAYER_SUB_ADD_CARD:
        {
            if (stReq.datas_size() == 2)
            {
                pstMainCtrl->m_stCardMgr.DropCard(stPlayerOnline._stUserCard, stReq.datas(0), stReq.datas(1));
                pstMainCtrl->m_stCardMgr.SendCardBagInfoToFront(stPlayerOnline._stUserCard, stMsgHead, stEnpHead);
                pstMainCtrl->m_stCardMgr.GetData(stPlayerOnline._stUserCard, stPlayerDetail._stUserCardData);
            }
        }
        break;  

    case ID_GM_PLAYER_SUB_ADD_CLAN_ITEM:   //增加家族物品
        {
            unsigned uiClanId = stPlayerDetail._stUserClan._uiClanId;
            int iIndex1 = pstMainCtrl->m_stClanMgr._stClanEntryHash.HashFind(uiClanId);
            if (iIndex1 < 0)
            {
                CT_ERROR(("%d", uiClanId));
                return AnsClients(ERROR_CLAN_NOT_EXIST);
            }

            if (stReq.datas_size() == 3)
            {          
                CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr._stClanEntryHash[iIndex1];
                short shCount = stReq.datas(2);
                stClanEntry._stStorage.AddAllItem(stReq.datas(0), stReq.datas(1), shCount, true);
                CT_TRACE(("%d, %d, %d", stReq.datas(0), stReq.datas(1), stReq.datas(2)));
            }
        }
        break;
    case ID_GM_PLAYER_SUB_SET_PET_EXPER:
        {
            int iPetExper = stReq.datas(0);
            iRet = pstMainCtrl->m_stPetMgr.GMPetTrain(stPlayerOnline._stUserPet, iPetExper);
        }
        break;
    case ID_GM_PLAYER_SUB_TEST: //测试用
        {
            iRet = RET_NOT_LOGIN;
        }
        break;

    case  ID_GM_PLAYER_SUB_ADD_BONUS_GIFT:
        {
            if (stReq.datas_size() == 2)
            {   
                pstMainCtrl->m_stItemMgr.DropBonus(OSS_MODULE_GM,_uiGID, stReq.datas(0), stReq.datas(1));
            }            
        }
        break;

    case ID_GM_PLAYER_SUB_SET_SYSOPEN:
        {
            stPlayerOnline._bCheckSysOpen = !stPlayerOnline._bCheckSysOpen;

            unsigned int uiNotifyType = NOTIFY_SYSOPEN_INFO;
            pstMainCtrl->m_stNotifyMgr.Notify(_uiGID, uiNotifyType);
        }
        break;

    case ID_GM_PLAYER_SUB_CLEAR_LES:
        {
            CUserLessonData& stUserLessonData = stPlayerDetail._stUserLessonData;
            stUserLessonData._iLastTakeRequiredLessonTime = 0;
            stUserLessonData._iLastTakeElectiveLessonTime = 0;
            stUserLessonData._iNextCanTakeLessonTime = 0;
        }
        break;
    case ID_GM_PLAYER_SUB_CLEAR_CLAN_BATTLE_DATA:
        {
            if (!pstMainCtrl->m_stClanBattleMgr.IsBegin())
            {
                pstMainCtrl->m_stClanBattleMgr.Clear();
                pstMainCtrl->m_stClanBattleMgr.ClearRank();
            }
            
        }
        break;
    case ID_GM_PLAYER_SUB_GET_MAGIC_DOOR:
        {
            iRet = pstMainCtrl->m_stMagicDoorMgr.GMDealMagicDoor(stPlayerDetail,
                stPlayerSnsDetailInfo, stReq, stAns);
        }
        break;
    case ID_GM_PLAYER_SUB_BUY_GOLD:
        {
            if (stReq.datas_size() != 2)
            {
                return AnsClients(RET_SYS_ERROR);
            }

            unsigned int uiGoodsId = (unsigned int)stReq.datas(0);
            int iCount = stReq.datas(1);

            iRet = pstMainCtrl->m_stShopMgr.DeliverGoods(stPlayerOnline, stPlayerBase, stPlayerDetail, stPlayerDetailInfoEx1,
                                        uiGoodsId, iCount, DELIVER_GOODS_OWN, stDropItem);
            if (RET_OK != iRet)
            {
                return AnsClients(iRet);
            }
            
            //活动触发
            pstMainCtrl->m_stActMgr.TriggerBuyGoods(stPlayerDetail._stSplendidAct, stPlayerBase._uiGID, 
                uiGoodsId, iCount, 0, stPlayerBase._stVipData._iPayGold);  

            pstMainCtrl->m_stNotifyMgr.Notify(stPlayerBase._uiGID, NOTIFY_SYSOPEN_INFO);
        }
        break;

    case ID_GM_PLAYER_SUB_DROP_TITLE:
        {
            if (stReq.datas_size() != 2)
            {
                return AnsClients(RET_SYS_ERROR);
            }

            if (stReq.datas(0) > MAX_ROLE_TITLE_CNT || stReq.datas(0) <= 0)
            {
                return AnsClients(ERROR_GM_INFO_NO_COMPLETE);
            }

            pstMainCtrl->m_stRoleMgr.DropTitle(_uiGID, (EN_ROLE_TITLE_TYPE)stReq.datas(0), pstMainCtrl->m_iNow + stReq.datas(1));
        }
        break;

    case ID_GM_PLAYER_SUB_CREATE_USERS:
        {
            const ::std::string & stStr = stReq.name();
            if (stStr.length() < 3 || stStr.length() >= 10)
            {
                return AnsClients(RET_SYS_ERROR);
            }

            CCmdGMCreateUsers* pstCreateUsers = (CCmdGMCreateUsers*) CT_CMDFACTORY->CreateCmd(ID_MAIN_GM_CREATE_USERS);
            if (!pstCreateUsers)
            {
                CT_WARNING(("factory create cmd(%d) failed.",ID_MAIN_GM_CREATE_USERS));
                return AnsClients(-1);
            }

            strncpy(pstCreateUsers->_szPrefixName, stStr.c_str(), stStr.length() + 1);

            pstCreateUsers->Do(0);
        }
        break;

    case ID_GM_PLAYER_SUB_SYS_OPEN_TEST:
        {
            if (stReq.datas_size() != 1)
            {
                return AnsClients(RET_SYS_ERROR);
            }

            MsgNotify stAns;

            PBMsgHead stMsgHeadTmp = stMsgHead;
            stMsgHead.set_msgid(ID_MAIN_NOTIFY);
            stMsgHead.set_msgret(RET_OK);
            stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

            MsgNotOpenSys* pstMsgNotOpenSys = stAns.mutable_not_open_sys();
            for (int i = 1; i <= SYS_OPEN_COND_ID_MAX; ++i)
            {
                if (stReq.datas(0) != i && !pstMainCtrl->m_stCommConfigLoader.IsOpen(i, stPlayerBase, stPlayerOnline))
                {
                    pstMsgNotOpenSys->add_not_open_sys_id(i);
                }
            }

            pstMainCtrl->m_stEncodeBuf.Clear();
            pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
            pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
            pstMainCtrl->NotifyOnlineUser(stPlayerBase._uiGID, pstMainCtrl->m_stEncodeBuf);

        }
        break;

    case ID_GM_PLAYER_SUB_SYS_RESET_GOLD_DIVINE:
        {
            stPlayerDetail._stUserDivine._stHasGoldDivineCount.Set(0, pstMainCtrl->m_iNow);
        }
        break;

    case ID_GM_PLAYER_SUB_SYS_RESET_CLAN_DAIL:
        {
           stPlayerDetail._stUserClan._stDailCnt.Set(0, pstMainCtrl->m_iNow);
        }
        break;
    
    case ID_GM_PLAYER_SUB_SYS_EXSPACE_TEST:
        {
            CDropItem stDropItem;
            
            if (stReq.datas_size() >= 3)
            {
                CDropItemData stDropItemData;
                stDropItemData._ucItemType = stReq.datas(0);
                stDropItemData._usItemConfigID = stReq.datas(1);
                stDropItemData._iItemCount = stReq.datas(2);

                stDropItem.Drop(stDropItemData);
            }

            for (int i = 0; i < stReq.items_size(); i++)
            {
                CDropItemData stData;
                const MsgGridItemInfo & stItem = stReq.items(i);
                stData._ucItemType = stItem.item_type();
                stData._usItemConfigID = stItem.item_config_id();
                stData._iItemCount = stItem.item_count();
                stDropItem.Drop(stData);
            }

            if (stDropItem.Size() > 0)
            {
                pstMainCtrl->m_stItemMgr.DropItemEx(NULL, stReq.gid(), stDropItem);
            }
        }
        break;

    case ID_GM_PLAYER_SUB_GET_SYSTEM_NOTICE:
        iRet = pstMainCtrl->m_stActMgr.GMDealSystemNotice(stReq, stAns);
        return AnsClients(iRet);

    case ID_GM_PLAYER_SUB_RESET_PYRAMID:
        {
            for (int i = 0; i < stPlayerDetail._stPyramidAct._astPyramidActDatas.Size(); ++i)
            {
                stPlayerDetail._stPyramidAct._astPyramidActDatas[i]._stHasResetCount.Set(0, pstMainCtrl->m_iNow);
            }
            
            
        }   
        break;

    case ID_GM_PLAYER_SUB_BUY_GROW_FUND:
        {
            stPlayerDetailInfoEx1._stPayActData._ucHasBuyGrowFund = 1;
        }
        break;

    case ID_GM_PLAYER_SUB_SET_BOX_BEGIN:
        {            
            if (1 == stReq.datas(0))
            {
                pstMainCtrl->m_stActMgr.StartFightForBox (stPlayerDetailInfoEx1._stFightForBox);
            }
            else
            {
                stPlayerDetailInfoEx1._stFightForBox.Clear();
            }            
        }
        break;

    case ID_GM_PLAYER_SUB_BUY_GOODS:
        {
            if (3 != stReq.datas_size())
            {
                return AnsClients(RET_SYS_ERROR);
            }
            
            pstMainCtrl->m_stVipMgr.PrepaidGold(stPlayerBase, stPlayerDetail, stReq.datas(2) / 10, true);
            pstMainCtrl->m_stActMgr.TriggerBuyGoods(stPlayerDetail._stSplendidAct, stPlayerBase._uiGID, stReq.datas(0), stReq.datas(1), stReq.datas(2), stPlayerBase._stVipData._iPayGold);
        }
        break;

    case ID_GM_PLAYER_SUB_SET_MOUNT_SOUL:
        {
            if (stReq.datas_size() != 2)
            {
                return AnsClients(RET_SYS_ERROR);
            }
   
            unsigned char ucColor = (unsigned char)stReq.datas(0);
            int iValue = stReq.datas(1);
            CMountData & stMountData = stPlayerDetailInfoEx1._stMount;
            switch (ucColor)
            {
            case MOUNT_COLOR_GREEN:
                {
                    stMountData._iGreen = iValue;
                }
                break;
            case MOUNT_COLOR_BLUE:
                {
                    stMountData._iBlue = iValue;
                }
                break;
            case MOUNT_COLOR_PURPLE:
                {
                    stMountData._iPurple = iValue;
                }
                break;
            case MOUNT_COLOR_GOLD:
                {
                    stMountData._iGolden = iValue;
                }
                break;
            case 5:
                {
                    stMountData._sGoldHuntCnt.Set(0, CMainCtrl::m_pstMain->m_iNow);
                }
                break;
            case 6:
                {
                    stMountData.Clear();
                }
                break;
            default:
                return AnsClients(RET_SYS_ERROR);
            }
        }
        break;

    case ID_GM_PLAYER_SUB_SET_CHANGE_BOX_POINT:
        {
            if (stReq.datas_size() < 1)
            {
                return AnsClients(RET_SYS_ERROR);
            }

            stPlayerDetailInfoEx1._stFightForBox._ashAllPoint[0] = stReq.datas(0);
        }
        break;

    case ID_GM_PLAYER_SUB_CREATE_SUPER_TEAM: //创建超级队伍
        {
            const int ATTR_VALUE = 500000;

            //主角升级
            if (stPlayerBase._shLevel < OPEN_ROLE_LEVEL)
            {
                MsgReqGMPlayer stLevelUpReq;
                stLevelUpReq.set_sub_type(ID_GM_PLAYER_SUB_ADD_LEVEL);
                stLevelUpReq.add_datas(OPEN_ROLE_LEVEL);

                iRet = pstMainCtrl->m_stRoleMgr.GMDealRole(stPlayerBase, stPlayerDetail, stPlayerOnline, stLevelUpReq, stAns);
                if(!iRet)
                {
                    iRet = GetInfoByGID(stPlayerBase, stPlayerDetail, stPlayerOnline);
                }
                uiNotifyType |= NOTIFY_ROLE_INFO;
            }

            //修改主角属性
            {
                MsgReqGMPlayer stModAttrReq;
                stModAttrReq.set_sub_type(ID_GM_PLAYER_SUB_ROLE_ATTR);
                stModAttrReq.add_datas(-1);
                stModAttrReq.add_datas(ATTR_VALUE);

                pstMainCtrl->m_stRoleMgr.GMDealRole(stPlayerBase, stPlayerDetail, stPlayerOnline, stReq, stAns);
            }
    
            //招募伙伴
            for (short i = 1; i <= 29; ++i)
            {
                if (stPlayerOnline._stUserPartner._astOnlineData.Size() >= 4)
                {
                    break;
                }
                
                stPlayerBase._i64Silver = (int64)999999999;
                stPlayerDetail._iReputation = 999999999;

                MsgAnsPartner stAnsTmp;
                pstMainCtrl->m_stPartnerMgr.PartnerJoin(i,
                    CPartnerMgr::PARTNER_JOIN_TYPE_NORMAL, stPlayerBase,
                    stPlayerDetail, stUnactPartnerInfo, stPlayerOnline,
                    stPlayerDetailInfoEx1, stAnsTmp);
            }

            //修改伙伴等级
            for (int i = 0; i < stPlayerOnline._stUserPartner._astOnlineData.Size(); ++i)
            {
                MsgReqGMPlayer stPartnerLevelUpReq;
                stPartnerLevelUpReq.set_sub_type(ID_GM_PLAYER_SUB_CHG_PARTNER_LEVEL);
                stPartnerLevelUpReq.add_datas(stPlayerOnline._stUserPartner._astOnlineData[i]._shResID);
                stPartnerLevelUpReq.add_datas(OPEN_ROLE_LEVEL);

                pstMainCtrl->m_stPartnerMgr.GMDealPartner(stPlayerBase,
                    stPlayerDetail, stPlayerOnline, stUnactPartnerInfo,
                    stPlayerDetailInfoEx1, stPartnerLevelUpReq, stAns);
            }

            //伙伴上阵
            char chPos = 0;
            char chOrder = 0;
            pstMainCtrl->m_stMatrixMgr.GetPlayerPosAndOrder(stPlayerBase, stPlayerDetail, chPos, chOrder);

            for (int i = 1; i <= MAX_MATRIX_UNIT_COUNT; ++i)
            {
                if (chPos == i)
                {
                    continue;
                }
                
                MsgAnsMatrix stAnsTmp;
                MsgReqMatrix stReqTmp;
                stReqTmp.set_matrix_idx(0);
                MsgMatrixUnit* pstReqUnit = stReqTmp.add_unit_datas();
                pstReqUnit->set_turn_order(0);
                pstReqUnit->set_type(GAME_OBJ_TYPE_PARTNER);
                pstReqUnit->set_order(0);
                pstReqUnit->set_pos(i);

                for (int j = 0; j < stPlayerOnline._stUserPartner._astOnlineData.Size(); ++j)
                {
                    short shResID = stPlayerOnline._stUserPartner._astOnlineData[j]._shResID;
                    if (pstMainCtrl->m_stMatrixMgr.PartnerInMainMatrix(stPlayerDetail, shResID))
                    {
                        continue;
                    }
                    
                    pstReqUnit->set_id(shResID);
                }

                pstMainCtrl->m_stMatrixMgr.AddToMatrix(stPlayerBase, stPlayerDetail, stPlayerOnline, stReqTmp, stAnsTmp);
            }

            //修改属性
            for (int i = 0; i < stPlayerOnline._stUserPartner._astOnlineData.Size(); ++i)
            {
                short shResID = stPlayerOnline._stUserPartner._astOnlineData[i]._shResID;
                if (!pstMainCtrl->m_stMatrixMgr.PartnerInMainMatrix(stPlayerDetail, shResID))
                {
                    continue;
                }

                MsgReqGMPlayer stPartnerLevelUpReq;
                stPartnerLevelUpReq.set_sub_type(ID_GM_PLAYER_SUB_PARTNER_ATTR);
                stPartnerLevelUpReq.add_datas(shResID);
                stPartnerLevelUpReq.add_datas(-1);
                stPartnerLevelUpReq.add_datas(ATTR_VALUE);

                pstMainCtrl->m_stPartnerMgr.GMDealPartner(stPlayerBase,
                    stPlayerDetail, stPlayerOnline, stUnactPartnerInfo,
                    stPlayerDetailInfoEx1, stPartnerLevelUpReq, stAns);
            }
            
            pstMainCtrl->m_stMatrixMgr.NotifyMatrix(stPlayerBase,
                stPlayerDetail, stPlayerOnline);
        }
        break;

    case ID_GM_PLAYER_SUB_GET_ACT_INFO://查看指定活动数据
        {
            if (stReq.datas_size() < 1)
            {
                return AnsClients(RET_REQ_NOT_COMPLETE);
            }

            switch (stReq.datas(0))
            {
            case ACT_ID_FIGHT_END://一战到底
                {
                    iRet = pstMainCtrl->m_stFightEndMgr.GMDealFightEnd(
                        stPlayerDetailInfoEx1, stAns);
                }
                break;
            default:
                return AnsClients(RET_INVALID_PARAM);
            }
        }
        break;

    case ID_GM_PLAYER_SUB_NEWSALES://新服特卖
        {
            if (stReq.datas_size() < 1)
            {
                return AnsClients(RET_REQ_NOT_COMPLETE);
            }

            switch (stReq.datas(0))
            {
            case 1: //
                {
                    stPlayerDetailInfoEx1._stNewSales.Clear();
                    stPlayerBase.SetActOpen(ACT_BIT_NEWSALES1);
                    stPlayerBase.SetActClose(ACT_BIT_NEWSALES2);
                }
                break;
            default:
                return AnsClients(RET_INVALID_PARAM);
            }
        }
        break;

    case ID_GM_PLAYER_SUB_ACA_CUP:
        {
            pstMainCtrl->m_stAcaCupMgr.GMRun();
        }
        break;

    case ID_GM_PLAYER_SUB_MARKET:
        {
            if (stReq.datas(0) == 0)
            {
                stPlayerDetailInfoEx1._stMarketTask._uiTaskId = CMarketMgr::TENCENT_MARKET_TASK_ID_1;
                stPlayerDetailInfoEx1._stMarketTask._ucIsFromMarket = true;
                stPlayerDetailInfoEx1._stMarketTask._ucHasFinish = false;
                stPlayerDetailInfoEx1._stMarketTask._ucHasGetAward = false;
            }
            else if (stReq.datas(0) == 1)
            {
                stPlayerDetailInfoEx1._stMarketTask._uiTaskId = CMarketMgr::TENCENT_MARKET_TASK_ID_1;
                stPlayerDetailInfoEx1._stMarketTask._ucIsFromMarket = true;
                stPlayerDetailInfoEx1._stMarketTask._ucHasGetAward = false;
                pstMainCtrl->m_stMarketMgr.AcceptTask (stPlayerDetailInfoEx1._stMarketTask, stPlayerOnline);
            }
            else if (stReq.datas(0) == 2)
            {
                pstMainCtrl->m_stMarketMgr.InfomTaskCompleted(_uiGID);
            }
            else if (stReq.datas(0) == 3)
            {
                pstMainCtrl->m_stMarketMgr.ProvideAward(stPlayerDetailInfoEx1._stMarketTask, stPlayerOnline, 508, 1);
            }
        }
        break;

    case ID_GM_PLAYER_SUB_REWARD_BACK: //奖励找回
        {
            iRet = pstMainCtrl->m_stRewardBackMgr.GMDeal(stPlayerBase,
                stPlayerDetailInfoEx1, stReq, stAns);
        }
        break;

    case ID_GM_PLAYER_SUB_ROCK_SCORE: //摇摇乐修改积分
        {
            if (stReq.datas_size() < 1)
            {
                return AnsClients(RET_REQ_NOT_COMPLETE);
            }

            stPlayerDetailInfoEx1._stSplendidActEx1._iRockScore += stReq.datas(0);
            stPlayerDetailInfoEx1._stSplendidActEx1._iRockScoreSum += stReq.datas(0);
            if (stPlayerDetailInfoEx1._stSplendidActEx1._iRockScore < 0)
            {
                stPlayerDetailInfoEx1._stSplendidActEx1._iRockScore = 0;
            }
            if (stPlayerDetailInfoEx1._stSplendidActEx1._iRockScoreSum < 0)
            {
                stPlayerDetailInfoEx1._stSplendidActEx1._iRockScoreSum = 0;
            }
        }
        break;

    default:
        iRet = ERROR_MAIN_SUB_CMD;
        break;
    }

    if (iRet)
    {
        return AnsClients(iRet);
    }

    //保存数据 base info
    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_BASE_INFO;
    stKey.m_u64ID = _uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerBase, VOP_UPDATE);

    //保存数据 detail info
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    stKey.m_u64ID = _uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetail, VOP_UPDATE);

    stPlayerSnsDetailInfo._stCommInfo._usLevel = stPlayerBase._shLevel;
    stKey.m_chDataType = DT_PLAYER_SNS_DETAIL_INFO;
    stKey.m_u64ID = _uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerSnsDetailInfo, VOP_UPDATE);

    //保存数据 unact partner info
    stKey.m_chDataType = DT_PLAYER_UNACT_PARTNER;
    stKey.m_u64ID = _uiGID;
    pstMainCtrl->UpdateData(stKey, stUnactPartnerInfo, VOP_UPDATE);

    stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
    stKey.m_u64ID = _uiGID;
    pstMainCtrl->UpdateData(stKey, stPlayerDetailInfoEx1, VOP_UPDATE);

    //下发数据
    pstMainCtrl->m_stNotifyMgr.Notify(_uiGID, uiNotifyType);

    return AnsClients(RET_OK);
}

int CCmdGMPlayer::CallBack(int iRet)
{
    if (m_pstChild)
    {
        CCmdApi* pstCmd = (CCmdApi*)m_pstChild;
        CTLib::CTKeyValue& stTApiKeyValue = pstCmd->stAns._stTApiKeyValue;

        for (int i = 0; i < stTApiKeyValue._astKeyValueData.Size(); ++i)
        {
            CT_TRACE(("%s=%s", stTApiKeyValue._astKeyValueData[i]._szKey(), stTApiKeyValue._astKeyValueData[i]._szValue()));
        }
    }
    
    return AnsClients(RET_OK);
}

int CCmdGMPlayer::AnsClients(int iRet)
{
    pstMainCtrl->m_stEncodeBuf.Clear();

    stMsgHead.set_msgret(iRet);

    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);
    stMsgHead.set_msgret(iRet);
    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);

    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

int CCmdGMPlayer::GetInfoByGID(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline)
{
    CTSizeString<MAX_BATTLE_NAME_BUFF> szNameStr;

    szNameStr.Cat("帐号:%s ",stPlayerBase._sUserToken());
    szNameStr.Cat("昵称:%s ",stPlayerBase._sRoleName());
    szNameStr.Cat("GID:%u ",stPlayerBase._uiGID);
    szNameStr.Cat("性别:%d ",stPlayerBase._ucIsMale);
    szNameStr.Cat("职业:%d ",stPlayerBase._ucCareer);
    szNameStr.Cat("学院:%d ",stPlayerBase._ucAcademy);
    szNameStr.Cat("等级:%d ",stPlayerBase._shLevel);
    szNameStr.Cat("经验:%lld ",stPlayerBase._i64NowExp);
    szNameStr.Cat("VIP:%d ",stPlayerBase._chVipLevel);
    szNameStr.Cat("\n金币:%d ",stPlayerBase._iGold);
    szNameStr.Cat("银币:%lld ",stPlayerBase._i64Silver);
    szNameStr.Cat("硬币:%lld ",stPlayerBase._iRomany);
    szNameStr.Cat("声望:%d ",stPlayerDetail._iReputation);
    szNameStr.Cat("精力:%d ",
        stPlayerBase._stUserEnergy.GetEnergy(pstMainCtrl->m_iNow));
    szNameStr.Cat("魂力:%d ",stPlayerBase._iHunli);
    szNameStr.Cat("活跃度:%d ",stPlayerBase._stUserDailyTaskData._iLiveValuer);
    szNameStr.Cat("命运之力:%d ",stPlayerBase._iFateForce);
    szNameStr.Cat("\nBase地图信息(ID:%u X:%d Y:%d) ",stPlayerBase._uiMapID,
        stPlayerBase._usXPos,stPlayerBase._usYPos);
    szNameStr.Cat("Online地图信息(ID:%u X:%d Y:%d) ",stPlayerOnline._uiNowMapID,
        stPlayerOnline._usMapPosX,stPlayerOnline._usMapPosY);
    szNameStr.Cat("%d年%d月%d日%d时%d分%d秒 [%d]",
        CMainCtrl::m_pstMain->m_stTm.tm_year + 1900,
        CMainCtrl::m_pstMain->m_stTm.tm_mon + 1,
        CMainCtrl::m_pstMain->m_stTm.tm_mday,
        CMainCtrl::m_pstMain->m_stTm.tm_hour,
        CMainCtrl::m_pstMain->m_stTm.tm_min,
        CMainCtrl::m_pstMain->m_stTm.tm_sec,
        CMainCtrl::m_pstMain->m_iNow);
    szNameStr.Cat("\n冻结信息[登录:%d 发言:%d 金币:%d 银币:%d 背包:%d 仓库:%d]",
        stPlayerBase._stFreezeData._iLoginLimit,
        stPlayerBase._stFreezeData._iSpeakLimit,
        stPlayerBase._stFreezeData._iGoldLimit,
        stPlayerBase._stFreezeData._iSilverLimit,
        stPlayerBase._stFreezeData._iBagLimit,
        stPlayerBase._stFreezeData._iStorgeLimit);

    stAns.set_name(szNameStr.Get());
    return 0;
}

int CCmdGMPlayer::GetHelpInfo()
{
    CTSizeString<MAX_BATTLE_NAME_BUFF> sHelpInfo;

    sHelpInfo.Cat("%s\n","角色操作自己不需要输入GID,操作其他在线角色需要指定GID");
    sHelpInfo.Cat("%.32s -- 指令:%d 帐号\n", "通过帐号获取角色信息",ID_GM_PLAYER_SUB_INFO_TOKEN);
    sHelpInfo.Cat("%.32s -- 指令:%d GID\n", "通过GID获取角色信息",ID_GM_PLAYER_SUB_INFO_GID);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:金币,银币,吉普赛硬币\n", "修改角色金钱",ID_GM_PLAYER_SUB_ADD_MONEY);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:声望\n", "修改角色声望",ID_GM_PLAYER_SUB_ADD_REPU);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:\n", "获取激活伙伴列表",ID_GM_PLAYER_SUB_ACT_PARTNER);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:\n", "获取历史伙伴列表",ID_GM_PLAYER_SUB_LIST_PARTNER);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:\n", "修改伙伴好感度",ID_GM_PLAYER_SUB_CHG_PARTNER_FAVOR);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:等级\n", "修改角色等级",ID_GM_PLAYER_SUB_ADD_LEVEL);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:经验\n", "修改角色经验",ID_GM_PLAYER_SUB_ADD_EXP);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:魂力\n", "修改角色魂力",ID_GM_PLAYER_SUB_ADD_HUNLI);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:[2013-05-23 16:33:00]\n", "游戏时间比当前时间快",ID_GM_MAINCTRL_OFFSET_TIME);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:副本类型\n", "打开所有副本", ID_GM_INSTANCE_FULL);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:物品类型,物品配置,数量\n", "增加物品",ID_GM_PLAYER_SUB_ADD_ITEM);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:任意\n", "增加花园数据，一次加10",ID_GM_ADD_GARDEN_DATA);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:taskid\n", "设置任务完成",ID_GM_PLAYER_SUB_SET_FINISH_TASK);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:acadmy\n", "设置学院",ID_GM_PLAYER_SUB_SET_ACADMY);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:\n", "获取主阵形列表",ID_GM_PLAYER_SUB_GET_MATRIX);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:数量\n", "增加命运之力",ID_GM_PLAYER_SUB_ADD_FATE_FORCE);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:时间-seconds\n", "设置累计在线时间",ID_GM_PLAYER_SUB_DEFEND_ONLINE);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:时间-seconds\n", "设置离线时间",ID_GM_PLAYER_SUB_DEFEND_OFFLINE);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:怪物ID,数量\n", "杀怪",ID_GM_PLAYER_SUB_KILL_ENEMY);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:关卡ID\n", "关卡通关",ID_GM_PLAYER_SUB_FINISH_INSTANCE);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:伙伴ID 等级\n", "修改伙伴等级",ID_GM_PLAYER_SUB_CHG_PARTNER_LEVEL);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:伙伴ID 经验\n", "修改伙伴经验",ID_GM_PLAYER_SUB_CHG_PARTNER_EXP);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:\n", "查看角色战斗属性",ID_GM_PLAYER_SUB_ROLE_ATTR);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:伙伴ID\n", "查看伙伴战斗属性",ID_GM_PLAYER_SUB_PARTNER_ATTR);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:根据MsgReq输入参数\n", "内部工厂命令",ID_GM_PLAYER_SUB_SEND_INNER_CMD);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:VIP等级\n", "设置VIP等级",ID_GM_PLAYER_SUB_SET_VIP_LEVEL);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:\n", "查看角色秘宝",ID_GM_PLAYER_SUB_GET_TREASURE);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:秘宝ID\n", "设置角色秘宝",ID_GM_PLAYER_SUB_SET_TREASURE);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:变化灵力值(支持正负)\n", "设置角色灵力",ID_GM_PLAYER_SUB_SET_SPIRIT);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:随意\n", "刷新竞技场英雄榜",ID_GM_PLAYER_SUB_FLUSH_ARENA_HERO_LIST);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:精力值\n", "设置精力",ID_GM_PLAYER_SUB_SET_ENERGY);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:次数\n", "增加博物馆扫荡次数",ID_GM_PLAYER_SUB_ADD_MUSEUM_SWEEP_COUNT);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:任意\n", "查看角色状态",ID_GM_PLAYER_SUB_GET_STATUS);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:任意\n", "查看世界BOSS排名榜",ID_GM_PLAYER_SUB_GET_WORLD_BOSS_RANK);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:任意\n", "查看活动配置及状态",ID_GM_PLAYER_SUB_GET_ACT_STATUS);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:任意\n", "重置精英副本购买数量",ID_GM_PLAYER_SUB_RESET_ELITE_COUNT);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:任意\n", "重置秘境购买数量",ID_GM_PLAYER_SUB_RESET_SECRET_COUNT);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:任意\n", "设置每日任务活跃度",ID_GM_PLAYER_SUB_SET_DAILY_TASK);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:任意\n", "开启怪物攻城战",ID_GM_PLAYER_SUB_OPEN_ENEMY_ATK_CITY);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:状态ID (X秒后到期)\n", "修改角色状态信息",ID_GM_PLAYER_SUB_ADD_STATUS);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:卡片配置ID,卡片经验\n", "添加卡片",ID_GM_PLAYER_SUB_ADD_CARD);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:宠物经验\n", "修改宠物经验",ID_GM_PLAYER_SUB_SET_PET_EXPER);
    sHelpInfo.Cat("%.32s -- 指令:%d 参数:活动ID,开关(1或0)\n", "活动开关(1开启,0关闭)",ID_GM_PLAYER_SUB_SET_ACT_STATUS);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n", "设置每日任务中的taskid完成",ID_GM_PLAYER_SUB_SET_DAILY_TASK_FINISH);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n", "设置系统开放/关闭",ID_GM_PLAYER_SUB_SET_SYSOPEN);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n", "清理上课次数",ID_GM_PLAYER_SUB_CLEAR_LES);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n", "查看学院BOSS信息",ID_GM_PLAYER_SUB_GET_ACADEMY_BOSS_INFO);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n", "清理家族战数据",ID_GM_PLAYER_SUB_CLEAR_CLAN_BATTLE_DATA);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n", "查看魔界传送门",ID_GM_PLAYER_SUB_GET_MAGIC_DOOR);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:商品ID, 购买数量\n","充值",ID_GM_PLAYER_SUB_BUY_GOLD);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:活动ID,世界等级\n","修改部分活动世界等级",ID_GM_PLAYER_SUB_SET_BOSS_WORLD_LEVEL);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:活动ID,血量,辅助参数\n","修改部分活动怪物血量",ID_GM_PLAYER_SUB_SET_BOSS_MONSTER_HP);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n","重置金币占卜次数",ID_GM_PLAYER_SUB_SYS_RESET_GOLD_DIVINE);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n","物品掉落测试",ID_GM_PLAYER_SUB_SYS_EXSPACE_TEST);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n","查看活动系统提示",ID_GM_PLAYER_SUB_GET_SYSTEM_NOTICE);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n","初始化金字塔重置次数",ID_GM_PLAYER_SUB_RESET_PYRAMID);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n","购买成长基金",ID_GM_PLAYER_SUB_BUY_GROW_FUND);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n","开启宝箱争夺",ID_GM_PLAYER_SUB_SET_BOX_BEGIN);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:商品ID,商品数量,使用的Q分\n","模拟购买物品",ID_GM_PLAYER_SUB_BUY_GOODS);    
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:坐骑颜色, 骑魂数\n","修改坐骑魂力",ID_GM_PLAYER_SUB_SET_MOUNT_SOUL);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:修改到的分数\n","修改宝箱争夺分数",ID_GM_PLAYER_SUB_SET_CHANGE_BOX_POINT);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:活动ID\n","查看指定活动数据",ID_GM_PLAYER_SUB_GET_ACT_INFO);
    sHelpInfo.Cat("%.36s -- 指令:%d 参数:任意\n","操作学院杯", ID_GM_PLAYER_SUB_ACA_CUP);

    stAns.set_name(sHelpInfo.Get());

    return 0;
}

int CCmdGMPlayer::SendInnerReq()
{
    if (stReq.datas_size() <= 0 || !stReq.has_name())
    {
        return 0;
    }

    CTSizeString<CSMsgDef::EMT_MAX_MSGLEN> szMsgTmp;
    szMsgTmp.Set("%s",stReq.name().c_str());

    CTSizeString<CSMsgDef::EMT_MAX_MSGLEN> szMsgStr;
    CTBinhex::Decode((const char*)szMsgTmp.Get(), szMsgTmp.GetDataLen(),
        (char*)(szMsgStr()));

    //return pstMainCtrl->SendInnerCmd(_uiGID, stReq.datas(0), szMsgStr);
    return 0;
}


CT_REGISTER_ASYNCCMD(ID_MAIN_GM_CREATE_USERS, CCmdGMCreateUsers);
int CCmdGMCreateUsers::Do(void* pData)
{  
    return LogicDo(RET_OK);
}

int CCmdGMCreateUsers::LogicDo(int iRet)
{
    CMainCtrl * pstMainCtrl = CMainCtrl::m_pstMain;
    
    CTSizeString<20> stName;
    stName.Set("%s%d", _szPrefixName, _iHaveCreatedCount);
    
    if (_uiGid > 0 && 255 != _ucStage)
    {
        InitOnline(_uiGid);
    }

    switch (_ucStage)
    {
    case 0:
        {
            MsgReqLogin stReqLogin;
            stReqLogin.set_user_token (stName());
            stReqLogin.set_passwd ("hc2013"); 

            iRet = pstMainCtrl->SendInnerCmd(this, 0, ID_MAIN_LOGIN, stReqLogin, false);
        }
        break;

    case 1:
        {         
            MsgReqInitUserInfo stReqInit;
            stReqInit.set_gid (_uiGid);
            stReqInit.set_is_male (true);
            stReqInit.set_career (CAREER_1);
            stReqInit.set_role_name (stName());

            iRet = pstMainCtrl->SendInnerCmd(this, _uiGid, ID_MAIN_INIT_USER_INFO, stReqInit, false);
        }
        break;

    case 2:
        {
            MsgReqCommitTask stReqCommitTask;
            stReqCommitTask.set_gid (_uiGid);

            MsgReqAcceptTask stReqAcceptTask;
            stReqAcceptTask.set_gid(_uiGid);

            //任务id，NPC (1, 18)  (2, 18)  (3, 19)  (4, 19)
            char acCommitNpc[] = {18, 18, 19, 19};
            char acAcceptNpc[] = {-1, -1, -1, 4};
            int i = 0;
            do
            {
                stReqCommitTask.set_task_id (i + 1);
                stReqCommitTask.set_npc_id (acCommitNpc[i]);

                iRet = pstMainCtrl->SendInnerCmd(NULL, _uiGid, ID_MAIN_COMMIT_TASK, stReqCommitTask, false);
                if (iRet)
                {
                    CT_ERROR (("%d, %d, %d",_uiGid, i, iRet)) ;
                }

                stReqAcceptTask.set_task_id(i+2);
                stReqAcceptTask.set_npc_id(acAcceptNpc[i]);

                iRet = pstMainCtrl->SendInnerCmd(NULL, _uiGid, ID_MAIN_ACCEPT_TASK, stReqAcceptTask, false);
                if (iRet)
                {
                    CT_ERROR (("%d, %d, %d",_uiGid, i, iRet)) ;
                }

                i += 1;
            }while (i < 5);

            //移动到麻瓜小镇  102, 1689， 532
            MsgReqMoveTo stMoveTo;
            stMoveTo.set_gid(_uiGid);
            stMoveTo.set_map_id(102);
            stMoveTo.set_pos_x(1689);
            stMoveTo.set_pos_y(532);
            pstMainCtrl->SendInnerCmd (NULL, _uiGid, ID_MAIN_MAP_MOVE, stMoveTo, false);
        }        

    default:
        {
            _ucStage = 255;
            _iHaveCreatedCount += 1;
            
            CEnpNetHead stHead;
            pstMainCtrl->SetOffline(_uiGid, stHead);
            _uiGid = 0;

            if (_iHaveCreatedCount >= _iMaxUserCount)
            {
                return Done(RET_OK);
            }           

            PushQueue(RET_OK);
        }
        break;
    }

    if (iRet)
    {
        CT_ERROR(("%d, %d, %d", _ucStage, _uiGid, iRet));
        return Done(RET_OK);
    }

    return RET_OK;
}

int CCmdGMCreateUsers::CallBack(int iRet)
{
    if (iRet)
    {
        CT_ERROR(("%d, %d, %d", _ucStage, _uiGid, iRet));
        return Done(RET_OK);
    }

    switch (_ucStage)
    {
    case 0:
        {
            CCmdLogin * pstCmd = (CCmdLogin*)m_pstChild;
            _uiGid = pstCmd->stAns.gid();

            _ucStage += 1;
        }
        break;

    case 1:
    case 2:
        {
            _ucStage += 1;
        }
        break;        
    case 255:
        {
            _ucStage = 0;
        }
        break;
    default:
        return Done(RET_OK);
    }

    LogicDo(RET_OK);

    return RET_OK;
}

int CCmdGMCreateUsers::InitOnline (unsigned int uiGID)
{
    /*
    CMainCtrl * pstMainCtrl = CMainCtrl::m_pstMain;

    CEnpNetHead stHead;
    pstMainCtrl->SetOnline(_uiGid, stHead);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user base info error, uid = %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashAlloc(uiGID);
        if (iIndex < 0)
        {
            CT_ERROR((""));
            return Done(RET_SYS_ERROR);
        }        
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited)
    {
        iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
        if (iIndex < 0)
        {
            CT_ERROR(("get user detail info error, uid = %u", uiGID));
            return Done(RET_SYSTEM_FAIL);
        }
        CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

        iIndex = pstMainCtrl->m_stPlayerSnsDetailInfoHash.HashFind(uiGID);
        if (iIndex < 0)
        {
            CT_ERROR(("get user sns detail info error, uid = %u", uiGID));
            return Done(RET_SYSTEM_FAIL);
        }
        CPlayerSnsDetailInfo& stPlayerSnsDetailInfo = pstMainCtrl->m_stPlayerSnsDetailInfoHash[iIndex];

        int iRet = stPlayerOnlineData.InitData(uiGID, stPlayerBaseInfo, stPlayerDetailInfo, stPlayerSnsDetailInfo);
        if (iRet)
        {
            CT_ERROR(("%d, %d", _uiGid, iRet));
            return Done(RET_SYS_ERROR);
        }
    }

    stPlayerOnlineData._iDefendValidInfo = 1;
    stPlayerOnlineData._bIsTencentLogin = false;
    */

    return 0;
}
